package com.hawk.eye.framework.plugins;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;
import java.util.List;

/**
 * @className: PluginBeanRegister
 * @description:
 * @author: salad
 * @date: 2023/10/4
 **/
@Component
public class PluginBeanRegister implements BeanFactoryPostProcessor, ApplicationContextAware {

    private static ApplicationContext applicationContext;

    private static ConfigurableListableBeanFactory beanFactory;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        PluginBeanRegister.beanFactory = beanFactory;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        PluginBeanRegister.applicationContext = applicationContext;
    }

    public static <T> void regist(List<T> target){
        for (T item : target) {
            registerBean(item.getClass());
        }
    }

    private static <T> void registerBean(Class<T> item) {
        AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
        // 获取最优构造函数（通常按照参数数量和类型匹配）
        Constructor<?>[] constructors = item.getDeclaredConstructors();
        if (constructors.length == 0) {
            throw new IllegalStateException("No public constructors found for class " + item.getName());
        }
        Constructor<?> constructor = constructors[0];
        Parameter[] parameters = constructor.getParameters();
        Object[] args = new Object[parameters.length];
        // 获取构造函数参数的依赖
        for (int i = 0; i < parameters.length; i++) {
            Class<?> paramType = parameters[i].getType();
            args[i] = factory.getBean(paramType);
        }
        // 使用反射实例化对象
        T bean;
        try {
            bean = (T) constructor.newInstance(args);
        } catch (Exception e) {
            throw new RuntimeException("IAlarmLogStorage实例化失败",e);
        }
        // 注册为 Bean
        factory.autowireBeanProperties(bean, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
        factory.initializeBean(bean, bean.getClass().getName());
        // 在 Spring 容器中注册 Bean
        String name = bean.getClass().getSimpleName();
        beanFactory.registerSingleton(name.substring(0, 1).toLowerCase() + name.substring(1), bean);
    }

}
